using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WeatherSystem.API.Models
{
    /// <summary>
    /// 天气数据条目实体（EAV模式）
    ///
    /// 采用Entity-Attribute-Value模式实现动态天气数据存储，
    /// 支持灵活添加新的气象指标而无需修改数据库结构
    /// </summary>
    public class WeatherDataEntry
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 关联的城市ID
        /// </summary>
        [Required]
        public Guid CityId { get; set; }

        /// <summary>
        /// 数据记录时间（天气发生时间）
        /// </summary>
        [Required]
        public DateTime RecordedAt { get; set; }

        /// <summary>
        /// 数据来源（如：OpenWeatherMap、手动录入等）
        /// </summary>
        [MaxLength(50)]
        public string? Source { get; set; }

        /// <summary>
        /// 数据创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 关联的城市信息
        /// </summary>
        public virtual City? City { get; set; }

        /// <summary>
        /// 该天气数据条目对应的所有动态指标值
        /// </summary>
        public virtual ICollection<MetricValue> Metrics { get; set; } = new List<MetricValue>();
    }

    /// <summary>
    /// 指标值实体（EAV模式的属性-值）
    ///
    /// 存储具体的天气指标数据，如温度、湿度、气压等，
    /// 支持多种数据类型：decimal（数值）、string（文本）、int（整数）、boolean（布尔值）
    /// </summary>
    public class MetricValue
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 关联的天气数据条目ID
        /// </summary>
        [Required]
        public Guid WeatherDataEntryId { get; set; }

        /// <summary>
        /// 指标键名（如：temperature、humidity、pressure）
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string MetricKey { get; set; } = string.Empty;

        /// <summary>
        /// 指标原始值（以字符串形式存储）
        /// </summary>
        [Required]
        [MaxLength(500)]
        public string RawValue { get; set; } = string.Empty;

        /// <summary>
        /// 数据类型（decimal、string、int、boolean）
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string DataType { get; set; } = string.Empty;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 关联的天气数据条目
        /// </summary>
        public virtual WeatherDataEntry? WeatherDataEntry { get; set; }

        /// <summary>
        /// 关联的指标定义（包含指标元数据）
        /// </summary>
        public virtual MetricDefinition? Definition { get; set; }
    }

    /// <summary>
    /// 指标定义实体
    ///
    /// 定义天气指标的元数据，包括指标名称、单位、数据类型、验证规则等
    /// 用于确保数据一致性和提供指标的自描述信息
    /// </summary>
    public class MetricDefinition
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 指标键名（唯一标识符）
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string Key { get; set; } = string.Empty;

        /// <summary>
        /// 指标显示名称
        /// </summary>
        [Required]
        [MaxLength(200)]
        public string Name { get; set; } = string.Empty;

        /// <summary>
        /// 指标单位（如：°C、%、hPa、km/h）
        /// </summary>
        [MaxLength(20)]
        public string Unit { get; set; } = string.Empty;

        /// <summary>
        /// 指标描述信息
        /// </summary>
        [MaxLength(500)]
        public string? Description { get; set; }

        /// <summary>
        /// 数据类型（decimal、string、int、boolean）
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string DataType { get; set; } = string.Empty;

        /// <summary>
        /// 是否为必填指标
        /// </summary>
        public bool IsRequired { get; set; } = false;

        /// <summary>
        /// 是否为默认指标（在创建天气数据时自动包含）
        /// </summary>
        public bool IsDefault { get; set; } = false;

        /// <summary>
        /// 指标是否活跃（活跃指标才允许使用）
        /// </summary>
        public bool IsActive { get; set; } = true;

        /// <summary>
        /// 显示顺序（用于前端界面排序）
        /// </summary>
        public int DisplayOrder { get; set; } = 0;

        /// <summary>
        /// 验证规则（JSON格式，如范围、正则表达式等）
        /// </summary>
        [Column(TypeName = "TEXT")]
        public string? ValidationRules { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 关联的所有指标值
        /// </summary>
        public virtual ICollection<MetricValue> Values { get; set; } = new List<MetricValue>();
    }


    /// <summary>
    /// 城市实体
    ///
    /// 存储城市地理位置信息，包括经纬度、时区、坐标系等
    /// 支持自动数据采集功能配置
    /// </summary>
    public class City
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 城市名称
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string Name { get; set; } = string.Empty;

        /// <summary>
        /// 国家名称
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string Country { get; set; } = string.Empty;

        /// <summary>
        /// 纬度（精度到小数点后8位）
        /// </summary>
        [Required]
        [Column(TypeName = "decimal(10,8)")]
        public decimal Latitude { get; set; }

        /// <summary>
        /// 经度（精度到小数点后8位）
        /// </summary>
        [Required]
        [Column(TypeName = "decimal(11,8)")]
        public decimal Longitude { get; set; }

        /// <summary>
        /// 时区（如：Asia/Shanghai、UTC+8）
        /// </summary>
        [Required]
        [MaxLength(50)]
        public string TimeZone { get; set; } = string.Empty;

        /// <summary>
        /// 定位技术类型（GPS、IP地址、手动输入等）
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string LocationTechType { get; set; } = "GPS";

        /// <summary>
        /// 坐标系统（WGS84、GCJ02、BD09等）
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string CoordinateSystem { get; set; } = "WGS84";

        /// <summary>
        /// 城市是否活跃（活跃城市才允许数据采集和查询）
        /// </summary>
        public bool IsActive { get; set; } = true;

        /// <summary>
        /// 是否启用自动数据采集
        /// </summary>
        public bool AutoCollectEnabled { get; set; } = true;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 导航属性（仅保留Legacy表映射，用于迁移后清理）
        /// </summary>
    }

    /// <summary>
    /// 统计数据条目实体（动态统计EAV模式）
    ///
    /// 存储按时间维度聚合的统计数据，支持日统计、周统计、月统计等
    /// 同样采用EAV模式以支持动态统计指标
    /// </summary>
    public class StatisticsEntry
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 关联的城市ID
        /// </summary>
        [Required]
        public Guid CityId { get; set; }

        /// <summary>
        /// 统计类型（Daily、Weekly、Monthly等）
        /// </summary>
        [Required]
        [MaxLength(50)]
        public string StatisticType { get; set; } = string.Empty;

        /// <summary>
        /// 统计日期（统计的截止日期）
        /// </summary>
        [Required]
        public DateTime StatisticDate { get; set; }

        /// <summary>
        /// 用于计算此统计的数据点数量
        /// </summary>
        public int DataPointCount { get; set; } = 0;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 关联的城市信息
        /// </summary>
        public virtual City? City { get; set; }

        /// <summary>
        /// 该统计条目对应的所有统计值
        /// </summary>
        public virtual ICollection<StatisticValue> Values { get; set; } = new List<StatisticValue>();
    }

    /// <summary>
    /// 统计值实体（统计数据的EAV模式）
    ///
    /// 存储具体的聚合统计值，支持多种聚合类型：
    /// - avg：平均值
    /// - max：最大值
    /// - min：最小值
    /// - sum：总和
    /// - count：计数
    /// - dominant：主要值（适用于分类数据）
    /// </summary>
    public class StatisticValue
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 关联的统计条目ID
        /// </summary>
        [Required]
        public Guid StatisticsEntryId { get; set; }

        /// <summary>
        /// 指标键名（如：temperature、humidity等）
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string MetricKey { get; set; } = string.Empty;

        /// <summary>
        /// 聚合类型（avg、max、min、sum、count、dominant）
        /// </summary>
        [Required]
        [MaxLength(50)]
        public string AggregationType { get; set; } = string.Empty;

        /// <summary>
        /// 聚合值（以字符串形式存储）
        /// </summary>
        [Required]
        [MaxLength(500)]
        public string RawValue { get; set; } = string.Empty;

        /// <summary>
        /// 数据类型（decimal、string、int、boolean）
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string DataType { get; set; } = string.Empty;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 关联的统计条目
        /// </summary>
        public virtual StatisticsEntry? StatisticsEntry { get; set; }

        /// <summary>
        /// 关联的指标定义
        /// </summary>
        public virtual MetricDefinition? Definition { get; set; }
    }


    /// <summary>
    /// 用户实体
    ///
    /// 系统用户信息，包含认证、授权和安全相关信息
    /// 支持三种角色：ReadOnly（只读）、User（普通用户）、Admin（管理员）
    /// </summary>
    public class User
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 用户名
        /// </summary>
        [Required]
        [MaxLength(50)]
        public string Username { get; set; } = string.Empty;

        /// <summary>
        /// 邮箱地址
        /// </summary>
        [Required]
        [MaxLength(100)]
        [EmailAddress]
        public string Email { get; set; } = string.Empty;

        /// <summary>
        /// 密码哈希值（存储加密后的密码）
        /// </summary>
        [Required]
        [MaxLength(255)]
        public string PasswordHash { get; set; } = string.Empty;

        /// <summary>
        /// 密码盐值（用于增强密码安全性）
        /// </summary>
        [MaxLength(255)]
        public string? PasswordSalt { get; set; }

        /// <summary>
        /// 用户角色
        /// </summary>
        [Required]
        public UserRole Role { get; set; } = UserRole.User;

        /// <summary>
        /// 用户是否活跃
        /// </summary>
        public bool IsActive { get; set; } = true;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 最后登录时间
        /// </summary>
        public DateTime? LastLoginAt { get; set; }

        /// <summary>
        /// 失败登录尝试次数（用于账户锁定机制）
        /// </summary>
        public int FailedLoginAttempts { get; set; } = 0;

        /// <summary>
        /// 账户锁定结束时间
        /// </summary>
        public DateTime? LockoutEndTime { get; set; }

        /// <summary>
        /// 最后密码修改时间
        /// </summary>
        public DateTime? LastPasswordChangeAt { get; set; }

        /// <summary>
        /// 刷新令牌列表（支持多设备登录）
        /// </summary>
        public virtual ICollection<RefreshToken> RefreshTokens { get; set; } = new List<RefreshToken>();
    }

    /// <summary>
    /// 刷新令牌实体
    ///
    /// 用于JWT令牌的刷新机制，支持无感续期
    /// 记录令牌创建、撤销和IP地址等信息，增强安全性
    /// </summary>
    public class RefreshToken
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 关联的用户ID
        /// </summary>
        [Required]
        public Guid UserId { get; set; }

        /// <summary>
        /// 刷新令牌值
        /// </summary>
        [Required]
        [MaxLength(255)]
        public string Token { get; set; } = string.Empty;

        /// <summary>
        /// 令牌过期时间
        /// </summary>
        [Required]
        public DateTime ExpiresAt { get; set; }

        /// <summary>
        /// 令牌是否已被撤销
        /// </summary>
        public bool IsRevoked { get; set; } = false;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 撤销时间
        /// </summary>
        public DateTime? RevokedAt { get; set; }

        /// <summary>
        /// 创建时的IP地址
        /// </summary>
        [MaxLength(100)]
        public string? CreatedByIp { get; set; }

        /// <summary>
        /// 撤销时的IP地址
        /// </summary>
        [MaxLength(100)]
        public string? RevokedByIp { get; set; }

        /// <summary>
        /// 关联的用户
        /// </summary>
        public virtual User User { get; set; } = null!;
    }

    /// <summary>
    /// 数据采集日志实体
    ///
    /// 记录自动数据采集的执行情况，包括成功、失败、部分成功等状态
    /// 用于监控数据采集服务的运行状态和问题排查
    /// </summary>
    public class DataCollectionLog
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 关联的城市ID（可选，全局日志可能不关联特定城市）
        /// </summary>
        public Guid? CityId { get; set; }

        /// <summary>
        /// 采集状态（Success、Failed、Partial）
        /// </summary>
        [Required]
        [MaxLength(20)]
        public string Status { get; set; } = string.Empty;

        /// <summary>
        /// 日志消息或错误信息
        /// </summary>
        [MaxLength(500)]
        public string? Message { get; set; }

        /// <summary>
        /// 采集到的记录数量
        /// </summary>
        public int RecordsCollected { get; set; } = 0;

        /// <summary>
        /// 执行时间
        /// </summary>
        public DateTime ExecutionTime { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 执行持续时间（毫秒）
        /// </summary>
        public int? Duration { get; set; }

        /// <summary>
        /// 关联的城市信息
        /// </summary>
        public virtual City City { get; set; } = null!;
    }

    /// <summary>
    /// 系统配置实体
    ///
    /// 存储系统运行时配置项，支持动态配置更新
    /// 包括API密钥、数据采集间隔、缓存策略等配置
    /// </summary>
    public class SystemConfiguration
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        [Key]
        public Guid Id { get; set; } = Guid.NewGuid();

        /// <summary>
        /// 配置键名
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string ConfigKey { get; set; } = string.Empty;

        /// <summary>
        /// 配置值（以字符串形式存储，支持JSON）
        /// </summary>
        [Required]
        [MaxLength(500)]
        public string ConfigValue { get; set; } = string.Empty;

        /// <summary>
        /// 配置描述
        /// </summary>
        [MaxLength(200)]
        public string? Description { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
    }
}